package jdkrel._genericity;

import java.util.Date;

/**
 * https://www.cnblogs.com/wuqinglong/p/9456193.html
 *
 * 然后我们想要一个子类继承Pair
 * 在这个子类中，我们设定父类的泛型类型为Pair<Date>，
 * 在子类中，我们覆盖了父类的两个方法，我们的原意是这样的：将父类的泛型类型限定为Date，
 * 那么父类里面的两个方法的参数都为Date类型。
 * 所以，我们在子类中重写这两个方法一点问题也没有，实际上，
 * 从他们的@Override标签中也可以看到，一点问题也没有，实际上是这样的吗？
 * 分析：实际上，类型擦除后，父类的的泛型类型全部变为了原始类型Object，所以父类编译之后会变成下面的样子：
 *
 * public class Pair {
 *     private Object value;
 *
 *     public Object getValue() {
 *         return value;
 *     }
 *
 *     public void setValue(Object  value) {
 *         this.value = value;
 *     }
 * }
 *
 * 先来分析setValue方法，父类的类型是Object，而子类的类型是Date，参数类型不一样，这如果实在普通的继承关系中，根本就不会是重写，而是重载。
 * 我们在一个main方法测试一下，
 * 如果是重载，那么子类中两个setValue方法，一个是参数Object类型，一个是Date类型，可是我们发现，根本就没有这样的一个子类继承自父类的Object类型参数的方法。
 * 所以说，却是是重写了，而不是重载了。
 * 于是JVM采用了一个特殊的方法，来完成这项功能，那就是桥方法。
 *
 * （1）不能用类型参数替换基本类型。就比如，没有ArrayList<double>，只有ArrayList<Double>。因为当类型擦除后，ArrayList的原始类型变为Object，但是Object类型不能存储double值，只能引用Double的值。
 * 因为类型擦除之后，ArrayList<String>只剩下原始类型，泛型信息String不存在了。
 * 那么，运行时进行类型查询的时候使用下面的方法是错误的：if( arrayList instanceof ArrayList<String>)
 *
 * （2）泛型类中的静态方法和静态变量不可以使用泛型类所声明的泛型类型参数
 * 因为泛型类中的泛型参数的实例化是在定义对象的时候指定的，而静态变量和静态方法不需要使用对象来调用。对象都没有创建，如何确定这个泛型参数是何种类型，所以当然是错误的。
 * 但是要注意区分一种情况：在泛型方法中使用的T是自己在方法中定义的 T，而不是泛型类中的T。
 *
 */
public class DateInter extends Pair<Date> {

    @Override
    public void setValue(Date value) {
        super.setValue(value);
    }

    @Override
    public Date getValue() {
        return super.getValue();
    }


    public static void main(String[] args) throws ClassNotFoundException {
        DateInter dateInter = new DateInter();
        dateInter.setValue(new Date());
//        dateInter.setValue(new Object()); //编译错误
    }

}
